home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / games / sakiba / source / screen.c < prev    next >
Text File  |  2000-06-20  |  14KB  |  570 lines

  1. /*********************************************
  2.  
  3.     格闘シミュレーション「さきば」
  4.  
  5.                 画面
  6.  
  7.  *********************************************/
  8.  
  9. #include    <stdio.h>
  10. #include    <stdlib.h>
  11. #include    <string.h>
  12. #include    <sys\dos.h>
  13. #include    <sys\iocs.h>
  14.  
  15. #include    "sakiba.h"
  16. #include    "screen.h"
  17. #include    "chranim.h"
  18. #include    "pad.h"
  19. #include    "pattern.h"
  20.  
  21.  
  22. #define    SPRITE_FILE    "SAKIBA"        /* スプライトデータ */
  23.  
  24. #define    CHR_CX         32            /* キャラクタ表示位置 */
  25. #define    CHR_Y        100
  26.  
  27. #define    BAR_CX          1            /* 行動バー表示位置 */
  28. #define    BAR_Y        128
  29. #define    BAR_W         10            /* 1カウントの行動バーの長さ */
  30. #define    BAR_H          6
  31. #define    BAR_NUM         20            /* 描画するバーの数 */
  32.  
  33. #define    HP_CX          4            /* 体力表示位置 */
  34. #define    HP_Y          4
  35. #define    HP_H         12            /* 体力バーの高さ */
  36.  
  37. #define    COL_HP        0xffd0            /* 体力バーの色 */
  38. #define    COL_DAMAGE    0x27d0            /* ダメージ */
  39. #define    COL_BACK    0x1408            /* 下地 */
  40.  
  41. #define    NAME_X          4            /* キャラクタ名表示位置 */
  42. #define    NAME_Y         20
  43.  
  44. #define    ACT_X1          4            /* 行動表示位置 */
  45. #define    ACT_X2        148
  46. #define    ACT_Y        160
  47. #define    ACT_H         34
  48.  
  49. #define    MES_CX        128            /* メッセージ表示位置 */
  50. #define    MES_CY         64
  51.  
  52. /*** スプライトコード *****/
  53. #define    SPR_HITMARK    0x50d            /* ヒットマーク */
  54. #define    SPR_CURSOR    0x614            /* 入力カーソル */
  55.  
  56.  
  57. static int        bar_count;        /* 行動バー描画の個数 */
  58. static int        message_num;        /* 表示メッセージ番号 */
  59. static int        hit_count;        /* ヒットマーク */
  60.  
  61. unsigned short*    sprite_reg;            /* スプライト */
  62. unsigned long    anim_count = 0;            /* アニメーション用カウンタ */
  63.  
  64.  
  65. static COLOR    bar_color[ACT_MAX] = {            /* 行動バーの色 */
  66.             0xe010,            /* 防御 */
  67.             0xffd8,            /* 弱攻撃 */
  68.             0xffd8,            /* 強攻撃 */
  69.             0xfabe,            /* 攻撃後の隙 */
  70.             0x0708            /* 攻撃を受けた */
  71.         };
  72.  
  73. static unsigned short    message[MES_MAX][2] = {        /* メッセージ */
  74.                 {0x400, 4},    /* Ready */
  75.                 {0x104, 4},    /* Fight! */
  76.                 {0x108, 3},    /* K.O. */
  77.                 {0x40b, 2},    /* Win */
  78.                 {0x210, 2},    /* 1P */
  79.                 {0x312, 2}    /* 2P */
  80.             };
  81.  
  82.  
  83. /**********************
  84.     垂直帰線期間待ち
  85.  **********************/
  86. void    v_synch(void)
  87. {
  88.     pad_synch();            /* パッド同期処理 */
  89.     rand();                /* 乱数 */
  90.     anim_count++;            /* アニメーション用カウンタ */
  91.  
  92.     while ( !(_iocs_b_bpeek((void *)0xe88001) & 0x10) );    /* 垂直帰線期間 */
  93.     while ( _iocs_b_bpeek((void *)0xe88001) & 0x10 );    /* 垂直表示期間 */
  94. }
  95.  
  96. /***************************************
  97.     スプライト描画
  98.     引数    code = パターンコード
  99.         x, y = 描画位置
  100.  ***************************************/
  101. void    put_sprite(CODE code, int x, int y)
  102. {
  103.     *sprite_reg++ = (unsigned short)x;        /* x座標 */
  104.     *sprite_reg++ = (unsigned short)y;        /* y座標 */
  105.     *sprite_reg++ = code;                /* パターンコード */
  106.     *sprite_reg++ = 3;                /* プライオリティ */
  107. }
  108.  
  109. /*********************************
  110.     文字列描画
  111.     引数     str = 文字列
  112.         x, y = 描画位置
  113.  *********************************/
  114. void    draw_str(char* str, short x, short y)
  115. {
  116.     struct _symbolptr    ptr;
  117.  
  118.     ptr.x1 = x + 1;            /* 描画位置 */
  119.     ptr.y1 = y + 1;
  120.     ptr.string_address = str;    /* 文字列 */
  121.     ptr.mag_x = 1;            /* 倍率 */
  122.     ptr.mag_y = 1;
  123.     ptr.color = 0x4110;        /* 色 */
  124.     ptr.font_type = 1;        /* 16ドットフォント */
  125.     ptr.angle = 0;            /* 回転なし */
  126.     _iocs_symbol(&ptr);
  127.  
  128.     ptr.x1 = x;            /* 描画位置 */
  129.     ptr.y1 = y;
  130.     ptr.color = 0xffff;        /* 色 */
  131.     _iocs_symbol(&ptr);
  132. }
  133.  
  134. /***************************************
  135.     メッセージ描画
  136.     引数     num = メッセージ番号
  137.         x, y = 描画中心位置
  138.  ***************************************/
  139. void    draw_message(int num, short x, short y)
  140. {
  141.     CODE    code;
  142.     int    n;
  143.  
  144.     code = (CODE)message[num][0];            /* スプライトコード */
  145.        n =  (int)message[num][1];            /* 長さ */
  146.     x += -n*(16/2) + 16;
  147.     y += 16;
  148.     for (; n > 0; n--) {
  149.         put_sprite(code++, x, y);
  150.         x += 16;
  151.     }
  152. }
  153.  
  154.  
  155. /********************
  156.     メッセージ表示
  157.  ********************/
  158. static
  159. void    print_message(void)
  160. {
  161.     if ( message_num >= 0 ) {
  162.         if ( message_num < MES_1P ) {
  163.             draw_message(message_num, MES_CX, MES_CY);
  164.         }
  165.         else {
  166.             draw_message(message_num, MES_CX - 16, MES_CY);
  167.             draw_message(MES_WIN,     MES_CX + 16, MES_CY);
  168.         }
  169.     }
  170. }
  171.  
  172. void    draw_bar(int, int, COLOR, COLOR, Bool);        /* バー描画 */
  173.  
  174. /*************************************
  175.     行動バー描画
  176.     引数     act = 行動
  177.         x, y = 描画位置
  178.         half = 半分ずらすか
  179.          inp = 入力中か
  180.  *************************************/
  181. static
  182. void    draw_act_bar(ACTION* act, int x, int y, Bool half, Bool inp)
  183. {
  184.     ACTION*    p;
  185.     COLOR    col1, col2;
  186.     int    i, n, cnt;
  187.  
  188.     p = act;                    /* 行動 */
  189.     n = -1;
  190.     if ( (cnt = p->count) == 0 ) {
  191.         n = 8;
  192.         p++;
  193.         cnt = p->count;
  194.     }
  195.     for (i = 0; i < bar_count; i++) {
  196.         if ( n < 0 ) {                /* 行動表示 */
  197.             col1 = bar_color[p->kind];
  198.             col2 = (((p->kind == ACT_ATTACK1) || (p->kind == ACT_ATTACK2))
  199.                              && (cnt == 1)) ? 0x07c0 : 0x0000;
  200.         }
  201.         else if ( n > 0 ) {            /* 行動非表示 */
  202.             col1 = (inp && ((anim_count + n/2)/32 % 2))
  203.                     ? 0x0000 : (COLOR)(((n*3 - 1) << 11) |
  204.                             ((n*3 - 1) << 6) | ((n*3 - 1) << 1));
  205.             col2 = 0x0000;
  206.         }
  207.         else {                    /* 行動未定 */
  208.             col1 = 0x0000;
  209.             col2 = 0x0000;
  210.         }
  211.  
  212.         if ( half && (i == 0) ) {        /* 半分ずらす */
  213.             draw_bar(x, y, col1, col2, TRUE);
  214.             y += BAR_H/2;
  215.         }
  216.         else {
  217.             draw_bar(x, y, col1, col2, FALSE);
  218.             y += BAR_H;
  219.         }
  220.  
  221.         if ( n < 0 ) {
  222.             if ( --cnt == 0 ) {        /* 次の行動 */
  223.                 if ( (p->kind != ACT_ATTACK1) && (p->kind != ACT_ATTACK2) ) {
  224.                     p++;
  225.                     n = ((p->kind >= 0) || (mode == MODE_INPUT)) ? 8 : 0;
  226.                 }
  227.                 else {
  228.                     p++;
  229.                     cnt = p->count;
  230.                 }
  231.             }
  232.         }
  233.         else if ( n > 0 ) {
  234.             n--;
  235.         }
  236.     }
  237. }
  238.  
  239. /**************
  240.     体力描画
  241.  **************/
  242. static
  243. void    draw_hp(void)
  244. {
  245.     struct _fillptr    ptr;
  246.     CHR_PARAM*    chr;
  247.     short        x;
  248.  
  249.     ptr.y1 = HP_Y;
  250.     ptr.y2 = HP_Y + HP_H - 1;
  251.  
  252.     chr = &chr_param[PLAYER1];            /* プレイヤー1 */
  253.     x = 128 - HP_CX;
  254.     if ( chr->hit_point > 0 ) {            /* 体力 */
  255.         ptr.x1 = x - chr->hit_point;
  256.         ptr.x2 = x - 1;
  257.         ptr.color = COL_HP;
  258.         _iocs_fill(&ptr);
  259.     }
  260.     if ( chr->hit_point < chr->d_hp ) {        /* ダメージ */
  261.         ptr.x1 = x - chr->d_hp;
  262.         ptr.x2 = x - chr->hit_point - 1;
  263.         ptr.color = COL_DAMAGE;
  264.         _iocs_fill(&ptr);
  265.         if ( anim_count % 2 ) {
  266.             chr->d_hp--;
  267.         }
  268.     }
  269.     if ( chr->d_hp < HP_MAX ) {            /* 下地 */
  270.         ptr.x1 = x - HP_MAX;
  271.         ptr.x2 = x - chr->d_hp - 1;
  272.         ptr.color = COL_BACK;
  273.         _iocs_fill(&ptr);
  274.     }
  275.  
  276.     chr = &chr_param[PLAYER2];            /* プレイヤー2 */
  277.     x = 128 + HP_CX;
  278.     if ( chr->hit_point > 0 ) {            /* 体力 */
  279.         ptr.x1 = x;
  280.         ptr.x2 = x + chr->hit_point - 1;
  281.         ptr.color = COL_HP;
  282.         _iocs_fill(&ptr);
  283.     }
  284.     if ( chr->hit_point < chr->d_hp ) {        /* ダメージ */
  285.         ptr.x1 = x + chr->hit_point;
  286.         ptr.x2 = x + chr->d_hp - 1;
  287.         ptr.color = COL_DAMAGE;
  288.         _iocs_fill(&ptr);
  289.         if ( (anim_count % 4) == 0 ) {
  290.             chr->d_hp--;
  291.         }
  292.     }
  293.     if ( chr->d_hp < HP_MAX ) {            /* 下地 */
  294.         ptr.x1 = x + chr->d_hp;
  295.         ptr.x2 = x + HP_MAX - 1;
  296.         ptr.color = COL_BACK;
  297.         _iocs_fill(&ptr);
  298.     }
  299. }
  300.  
  301. /********************
  302.     キャラクタ描画
  303.  ********************/
  304. static
  305. void    draw_chr(void)
  306. {
  307.     int    i, j, k;
  308.  
  309.     if ( mode == MODE_INPUT ) {
  310.         put_sprite(SPR_CURSOR + ((anim_count/8) % 3),
  311.                 (turn == PLAYER1) ? (128 - CHR_CX + 8) : (128 + CHR_CX + 8),
  312.                                         CHR_Y - 20);
  313.                             /* 入力カーソル描画 */
  314.     }
  315.     for (i = 0; i < 2; i++) {
  316.         for (j = 0; j < 2; j++) {
  317.             if ( turn == (i ^ j) ) {
  318.                 for (k = 0; k < 2; k++) {
  319.                     draw_pat(&chr_param[j].spr[1 - k], j,
  320.                         (j == PLAYER1) ? (128 - CHR_CX)
  321.                                 : (128 + CHR_CX),
  322.                                         CHR_Y);
  323.                             /* キャラクタパターン描画 */
  324.                 }
  325.             }
  326.         }
  327.         if ( (i == 0) && (hit_count > 0) ) {
  328.             put_sprite(SPR_HITMARK + ((hit_count > 12) ? (14 - hit_count) : 2),
  329.                 (turn == PLAYER1) ? (128 + CHR_CX + 8) : (128 - CHR_CX + 8),
  330.                                         CHR_Y + 8);
  331.                             /* ヒットマーク描画 */
  332.             hit_count--;
  333.         }
  334.     }
  335. }
  336.  
  337. /**************
  338.     画面描画
  339.  **************/
  340. void    draw_screen(void)
  341. {
  342.     int    ssp;
  343.  
  344.     ssp = _iocs_b_super(0);            /* スーパーバイザモード */
  345.     sprite_reg = SPRITE_REG;        /* スプライトレジスタ先頭 */
  346.     v_synch();                /* 垂直同期 */
  347.  
  348.     print_message();            /* メッセージ描画 */
  349.     draw_chr();                /* キャラクタ描画 */
  350.     if ( bar_count < BAR_NUM ) {        /* 行動バー描画個数 */
  351.         bar_count++;
  352.     }
  353.     draw_act_bar(chr_param[PLAYER1].action, 128 - BAR_CX - BAR_W, BAR_Y,
  354.             (turn != PLAYER1), ((mode == MODE_INPUT) && (turn == PLAYER1)));
  355.     draw_act_bar(chr_param[PLAYER2].action, 128 + BAR_CX, BAR_Y,
  356.             (turn != PLAYER2), ((mode == MODE_INPUT) && (turn == PLAYER2)));
  357.                         /* 行動バー描画 */
  358.     draw_hp();                /* 体力描画 */
  359.  
  360.     while ( (unsigned long)sprite_reg < (unsigned long)(SPRITE_REG + 4*0x100) ) {
  361.         sprite_reg += 3;
  362.         *sprite_reg++ = 0;        /* スプライト非表示 */
  363.     }
  364.     _iocs_b_super(ssp);            /* ユーザーモード */
  365. }
  366.  
  367.  
  368. /**********************************
  369.     行動バーを徐々に描画
  370.     引数    f = 描画を待つか
  371.  **********************************/
  372. void    slow_bar(Bool f)
  373. {
  374.     bar_count = 0;                /* 行動バー描画個数 */
  375.     if ( f ) {
  376.         while ( bar_count < BAR_NUM ) {
  377.             draw_screen();        /* 画面描画 */
  378.             if ( esc_key ) {
  379.                 return;
  380.             }
  381.         }
  382.     }
  383. }
  384.  
  385. /**************************************
  386.     表示メッセージ設定
  387.     引数    num = メッセージ番号
  388.  **************************************/
  389. void    set_message(int num)
  390. {
  391.     message_num = num;
  392. }
  393.  
  394. /**********************
  395.     ヒットマーク設定
  396.  **********************/
  397. void    set_hitmark(void)
  398. {
  399.     hit_count = 14;
  400. }
  401.  
  402.  
  403. /*********************************************
  404.     パターン描画
  405.     引数     pat = グラフィックパターン
  406.         x, y = 描画位置
  407.  *********************************************/
  408. static
  409. void    draw_g_pattern(COLOR* pat, short x, short y)
  410. {
  411.     struct _putptr    ptr;
  412.  
  413.     ptr.x1 = x;            /* 描画位置 */
  414.     ptr.y1 = y;
  415.     ptr.x2 = x + 16 - 1;
  416.     ptr.y2 = y + 16 - 1;
  417.     ptr.buf_start = pat;        /* グラフィックパターン */
  418.     ptr.buf_end   = pat + 16*16;
  419.     _iocs_putgrm(&ptr);
  420. }
  421.  
  422. /*********************************
  423.     行動バー描画(横書き)
  424.     引数    x, y = 描画位置
  425.          num = 個数
  426.          col = 色
  427.  *********************************/
  428. static
  429. void    draw_bar2(short x, short y, int num, COLOR col)
  430. {
  431.     struct _fillptr    ptr;
  432.  
  433.     ptr.x1 = x;                /* 描画位置 */
  434.     ptr.x2 = x + BAR_H - 2;
  435.     ptr.y1 = y;
  436.     ptr.y2 = y + BAR_W - 1;
  437.     ptr.color = col;            /* 色 */
  438.     for (; num > 0; num--) {
  439.         _iocs_fill(&ptr);
  440.         ptr.x1 += BAR_H;
  441.         ptr.x2 += BAR_H;
  442.     }
  443. }
  444.  
  445. /**********************************
  446.     行動描画
  447.     引数    num = プレイヤー
  448.  **********************************/
  449. static
  450. void    draw_action(int num)
  451. {
  452.     CHR_DATA*    chr;
  453.     short        x, y;
  454.  
  455.     chr = chr_param[num].data;            /* キャラクタデータ */
  456.     x = (num == PLAYER1) ? ACT_X1 : ACT_X2;
  457.     y = ACT_Y;
  458.  
  459.     draw_g_pattern((num == PLAYER1) ? l_arrow : r_arrow, x, y);
  460.     draw_bar2(x + 28, y + 12, GUARD_CNT, bar_color[ACT_GUARD]);
  461.     draw_str("防御", x + 18, y);            /* 防御 */
  462.     y += ACT_H;
  463.  
  464.     draw_g_pattern((num == PLAYER1) ? r_arrow : l_arrow, x, y);
  465.     draw_bar2(x + 28, y + 12, chr->attack1.before, bar_color[ACT_ATTACK1]);
  466.     draw_bar2(x + 28 + chr->attack1.before*BAR_H, y + 12,
  467.                         chr->attack1.after, bar_color[ACT_SUKI]);
  468.     draw_str(chr->attack1.name, x + 18, y);        /* 弱攻撃 */
  469.     y += ACT_H;
  470.  
  471.     draw_g_pattern(u_arrow, x, y);
  472.     draw_bar2(x + 28, y + 12, chr->attack2.before, bar_color[ACT_ATTACK2]);
  473.     draw_bar2(x + 28 + chr->attack2.before*BAR_H, y + 12,
  474.                         chr->attack2.after, bar_color[ACT_SUKI]);
  475.     draw_str(chr->attack2.name, x + 18, y);        /* 強攻撃 */
  476. }
  477.  
  478. /******************
  479.     初期画面描画
  480.  ******************/
  481. void    draw_start(void)
  482. {
  483.     _iocs_wipe();                /* グラフィッククリア */
  484.  
  485.     draw_str(chr_param[PLAYER1].data->name, NAME_X, NAME_Y);
  486.     draw_str(chr_param[PLAYER2].data->name,
  487.             256 - NAME_X - strlen(chr_param[PLAYER2].data->name)*8, NAME_Y);
  488.                         /* キャラクタ名描画 */
  489.  
  490.     draw_action(PLAYER1);            /* 行動描画 */
  491.     draw_action(PLAYER2);
  492.  
  493.     bar_count = BAR_NUM;            /* 行動バー描画個数 */
  494.     set_message(-1);            /* メッセージ無し */
  495.  
  496.     _iocs_contrast(-2);            /* フェードイン */
  497. }
  498.  
  499.  
  500. /*****************************************************
  501.     スプライトデータ読み込み
  502.     引数     sp_name = スプライトファイルネーム
  503.         pal_name = パレットファイルネーム
  504.               sp = 先頭コード
  505.              pal = 先頭パレット
  506.     戻り値    0 : 読み込み完了
  507.         1 : 読み込み失敗
  508.  *****************************************************/
  509. int    load_sprite(char* sp_name, char* pal_name, int sp, int pal)
  510. {
  511.     FILE*    fp;
  512.     char    *buf, *p;
  513.     unsigned short*    c;
  514.     int    i, j, size;
  515.  
  516.     if ( (buf = malloc(0x8000)) == NULL ) {
  517.         eprintf("メモリが足りません\n");
  518.         return    1;
  519.     }
  520.  
  521.     sprintf(buf, "%s.SP", sp_name);                /* パターンデータ */
  522.     if ( (fp = fopen(buf, "rb")) == NULL ) {
  523.         eprintf("パターンファイル \"%s\" が開けません\n", buf);
  524.         return    1;
  525.     }
  526.     size = fread(buf, 0x80, 0x100, fp);
  527.     fclose(fp);
  528.  
  529.     for (i = 0, p = buf; i < size; i++, p += 0x80) {
  530.         _iocs_sp_defcg(sp++, 1, p);            /* スプライト定義 */
  531.     }
  532.  
  533.     sprintf(buf, "%s.PAL", pal_name);            /* パレットデータ */
  534.     if ( (fp = fopen(buf, "rb")) == NULL ) {
  535.         eprintf("パレットファイル \"%s\" が開けません\n", buf);
  536.         return    1;
  537.     }
  538.     size = fread(buf, sizeof(short)*0x10, 0x0f, fp);
  539.     fclose(fp);
  540.  
  541.     c = (unsigned short*)buf;
  542.     for (j = 0; j < size; j++, pal++) {
  543.         for (i = 0; i < 0x10; i++) {
  544.             _iocs_spalet(i + (1 << 0x1f), pal, (int)*c++);
  545.                                 /* パレット定義 */
  546.         }
  547.     }
  548.  
  549.     free(buf);
  550.     return    0;
  551. }
  552.  
  553. /********************************
  554.     画面初期化
  555.     戻り値    0 : 初期化完了
  556.         1 : 初期化失敗
  557.  ********************************/
  558. int    init_screen(void)
  559. {
  560.     _iocs_contrast(0);                /* フェードアウト */
  561.     _iocs_sp_init();                /* スプライト画面初期化 */
  562.     _iocs_sp_on();                    /* スプライト画面表示 */
  563.     if ( load_sprite(SPRITE_FILE, SPRITE_FILE, 0x00, 0x01) ) {
  564.                             /* スプライト読み込み */
  565.         return    1;
  566.     }
  567.     return    0;
  568. }
  569.  
  570. /************************ End of File *************************************************/